# -*- coding: utf-8 -*-
from multiprocessing import Pool
import pytest, time, threading, os

"""
多线程并发+多驱动执行用例
缺点：
    1、线程执行的用例需要自己指定 参数 themes
    2、线程数需要自己修改，修改完线程数后需要修改 themes
    

"""


# 命令模块
def run_parallel(theme):
    # pytest.main([f"--cmdopt={theme}", f"./test_case/{theme}", "--alluredir", "./allure/allure-results"])
    pytest.main([f"./test_case/{theme}", "--alluredir", "./allure/allure-results"])


# 输入的格式固定的三层数组，几个线程几组数据(   [[],[]] 为一组数据  )，目前两组数据两个线程
themes = [[['test_BaiDu.py', 'test_one.py'], ['test_BaiDu.py', 'test_one.py']],
          [['test_BaiDu.py', 'test_one.py'], ['test_BaiDu.py', 'test_one.py']]]


def pytest_start(themes):
    for theme in themes:
        with Pool(len(theme)) as pool:
            pool.map(run_parallel, theme)
            pool.close()
            pool.join()


class myThread(threading.Thread):
    def __init__(self, threadID, name, delay):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.delay = delay

    def run(self):
        """
        将脚本使用线程执行
        :return:
        """
        print("开始线程：" + self.name)
        for theme in themes:
            pytest_start(theme)  # 执行的脚本封装模块
        print("退出线程：" + self.name)
        # 统合当前线程的报告 一个线程一个报告（执行多少个线程多少个报告）
        times = time.strftime("%m_%d_%H_%M_%S")
        path = f'./allure/{times + self.name}'  # 报告路径+名称
        os.system(f'allure generate ./allure/allure-results -o {path} --clean')  # 统合当前线程报告命令


threads = []
name = locals()  # 为变量名拼接做准备
for i in range(2):  # 生成的线程数
    name['thread' + str(i + 1)] = myThread(i + 1, f"Thread-{i + 1}", i + 1)  # 使用拼接变量名 赋值线程
    threads.append(name['thread' + str(i + 1)])  # 将线程添加进数组

if __name__ == '__main__':

    """
    case失败之后或者是调试时，进程不会结束。所以新执行测试之前需要先结束进程
    """
    os.system('taskkill /im msedgedriver.exe /F')  # 执行case之前结束 edge驱动进程
    os.system('taskkill /im chromedriver.exe /F')  # 执行case之前结束 Chrome驱动进程

    # 执行多线程
    for j in threads:
        j.start()  # 循环执行多线程
    for j in threads:
        j.join()


